home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / 3dvect37.zip / 3D3.ASM < prev    next >
Assembly Source File  |  1994-06-22  |  38KB  |  1,249 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ;
  3. ; Filename     : 3d3.asm
  4. ; Included from: Main Assembley Module
  5. ; Description  : 3d vector routines - fast sorting method with tolerenced full sorting (3d1+3d2)
  6. ;
  7. ; Written by: John McCarthy
  8. ;             1316 Redwood Lane
  9. ;             Pickering, Ontario.
  10. ;             Canada, Earth, Milky Way (for those out-of-towners)
  11. ;             L1X 1C5
  12. ;
  13. ; Internet/Usenet:  BRIAN.MCCARTHY@CANREM.COM
  14. ;         Fidonet:  Brian McCarthy 1:229/15
  15. ;   RIME/Relaynet: ->CRS
  16. ;
  17. ; Home phone, (905) 831-1944, don't call at 2 am eh!
  18. ;
  19. ; Send me your protected mode source code!
  20. ; Send me your Objects!
  21. ; But most of all, Send me a postcard!!!!
  22. ;
  23. ; - objects can pass through one another and still be sorted correctly
  24. ; - maxsurfs and maxpoints must be large - set to TOTAL points/surfs on screen
  25. ;
  26. ; To use:
  27. ;
  28. ;          call draw_landscape       ; draw background landscape
  29. ;          call clear_fill         ; clear video memory (last screen)
  30. ;          call look_at_it         ; make camera look at selected object
  31. ;          call setsincose         ; set rotation multipliers for eye
  32. ;          call show_stars         ; plot background stars (if you want)
  33. ;          call makeobjs           ; plot all objects in sides table
  34. ;          call instant_mouse      ; plot mouse on screen
  35. ;          call flip_page          ; flip video pages
  36. ;          call resetupd           ; reset update for borders
  37. ;          call updvectors         ; move objects around, rotate them
  38. ;
  39. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  40.  
  41.            .386p
  42.            jumps
  43.  
  44. code32     segment para public use32
  45.            assume cs:code32, ds:code32
  46.  
  47. ; define externals
  48.  
  49.            include pmode.ext       ; protected mode externals
  50.            include xmouse.ext      ; xmode mouse externals
  51.            include xmode.ext       ; xmode externals by matt pritchard
  52.            include irq.ext
  53.            include font.ext
  54.  
  55.            include macros.inc
  56.            include equ.inc
  57.  
  58.            include vars3.inc       ; labels and such
  59.            align 16
  60.            include arctan.inc      ; inverse tan
  61.            include sin.inc         ; sin/cosin table
  62.            include math.inc        ; rotate, cos,sin,arctan...
  63.            include xscale.inc
  64.            include poly.inc        ; common ploygon stuff
  65.            include more.inc        ; more common 3d/graphics stuff
  66.  
  67.            public makeobjs
  68.            public make1obj
  69.            public flush_surfaces
  70.            public init_tables
  71.  
  72.            strip_bytes equ 8
  73.  
  74.            align 16
  75.  
  76. abort_all:
  77.            add esp,strip_bytes    ; abort from loadpoints and make1obj
  78.            ret                    ; returning now from makeobjs call
  79.  
  80.            align 16
  81.  
  82. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  83. ; Loadpoints:  Begin loading of points from object definition data into array
  84. ; In:
  85. ;  ESI -> object #
  86. ; Out:
  87. ;  ESI -> offset of connection data
  88. ; Given ESI as object number.  rotate, translate and convert to 3d the points
  89. ; of that object.  returns edi as pointer to sides.
  90. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  91.  
  92. loadpoints:
  93.            mov bl,userotate[esi]  ; rotation type
  94.  
  95.            mov si,whatshape[esi*2] ; get shape
  96.            mov esi,objbase[esi*4]
  97.  
  98. view_is_not_ok:
  99.            mov eax,[esi]
  100.            add esi,8
  101.  
  102.            cmp eax,zad            ; check if too far to see detail anyway
  103.            jb s view_is_not_ok
  104.  
  105.            mov eax,[esi-4]
  106.            add esi,eax
  107. llkk:
  108.            movzx eax,w [esi]
  109.            mov numpoints,eax
  110.  
  111.            or eax,eax
  112.            jz no_points_anyway
  113.  
  114.            mov edi,pointindex     ; set xp,yp,zp pointer
  115.  
  116.            shl eax,2
  117.            add eax,pointindex     ; pointindex = word indexer to last point
  118.            cmp eax,maxpoints*4-4  ; test for overflow in points tables
  119.            jae abort_all
  120.  
  121.            mov ax,[esi+2]
  122.            mov numsides,eax
  123.  
  124.            add eax,showing
  125.            cmp eax,maxsurfaces-1  ; check for overflow in "sides" tables
  126.            jae abort_all
  127.  
  128.            add esi,4+25*2         ; skip point and side totals, skip future data
  129.            mov lindex,edi         ; set last index to points (this one)
  130.  
  131.            add edi,4              ; compensate for center of gravity point
  132. middle_load_points:
  133.            test bl,no_rotation    ; check userotate command
  134.            jnz np13               ; use different loop if no rotation
  135. np12:
  136.            movsx ebx,w [esi]      ; x
  137.            movsx ecx,w [esi+2]    ; y
  138.            movsx ebp,w [esi+4]    ; z
  139.  
  140.            push edi esi
  141.            call rotate            ; rotate based on object matrix
  142.            add ebp,zad
  143.  
  144.            cmp ebp,ztruncate
  145.            jge s ntrunct
  146.            neg ebp
  147.            cmp ebp,ztruncate
  148.            jge s ntrunct
  149.            mov ebp,ztruncate
  150. ntrunct:
  151.            add ebx,xad
  152.            add ecx,yad
  153.            call make3d
  154.            pop esi edi
  155.            mov xp[edi],ebx
  156.            mov yp[edi],ecx
  157.            mov zp[edi],ebp
  158.            add edi,4              ; inc xp indexer
  159.            add esi,6              ; inc input pointer
  160.            dec numpoints
  161.            jne s np12
  162.  
  163.            mov pointindex,edi     ; save for next call of loadpoints
  164.  
  165.            ret                    ; esi exits with pointer to sides
  166.  
  167. no_points_anyway:
  168.            mov ax,[esi+2]
  169.            mov numsides,eax
  170.  
  171.            add eax,showing
  172.            cmp eax,maxsurfaces-1  ; check for overflow in "sides" tables
  173.            jae abort_all
  174.  
  175.            add esi,4+25*2         ; skip point and side totals, skip future data
  176.  
  177.            mov edi,pointindex     ; set xp,yp,zp pointer
  178.            add pointindex,4
  179.            mov lindex,edi         ; set last index to points (this one)
  180.            ret
  181. np13:
  182.            movsx ebx,w [esi]      ; x
  183.            movsx ecx,w [esi+2]    ; y
  184.            movsx ebp,w [esi+4]    ; z
  185.  
  186.            push edi esi
  187.            call erotate           ; rotation matrix already set up! (camera)
  188.            add ebp,zad
  189.  
  190.            cmp ebp,ztruncate
  191.            jge s ntrunct2
  192.            neg ebp
  193.            cmp ebp,ztruncate
  194.            jge s ntrunct2
  195.            mov ebp,ztruncate
  196. ntrunct2:
  197.            add ebx,xad
  198.            add ecx,yad
  199.            call make3d
  200.            pop esi edi
  201.            mov xp[edi],ebx
  202.            mov yp[edi],ecx
  203.            mov zp[edi],ebp
  204.            add edi,4              ; inc xp indexer
  205.            add esi,6
  206.            dec numpoints
  207.            jne s np13
  208.  
  209.            mov pointindex,edi     ; save for next call of loadpoints
  210.  
  211.            ret
  212.  
  213.            align 16
  214.  
  215. special_commands dd offset dobitmap
  216.                  dd offset dobitmap
  217.                  dd offset pushmatrix
  218.                  dd offset popmatrix
  219.                  dd offset pushlocation
  220.                  dd offset poplocation
  221.                  dd offset newobject
  222.                  dd offset no_new_matrix
  223.                  dd offset gosub_function  ; 8
  224.                  dd offset return_function ; 9
  225.                  dd offset goto_function   ; 10
  226.  
  227. number_ofb dw 5*2
  228.            dw 5*2
  229.            dw 1*2
  230.            dw 1*2
  231.            dw 1*2
  232.            dw 1*2
  233.            dw 1*2
  234.            dw 1*2
  235.            dw ?   ; gosub_function
  236.            dw ?   ; return_function
  237.            dw ?   ; goto_function
  238.  
  239.            align 16
  240. gosub_function:
  241.            push esi
  242.            movsx eax,w [esi]
  243.            add esi,eax
  244.            jmp return_iteration
  245.  
  246.            align 16
  247. return_function:
  248.            pop esi
  249.            add esi,2
  250.            jmp return_iteration
  251.  
  252.            align 16
  253. goto_function:
  254.            movsx eax,w [esi]
  255.            add esi,eax
  256.            jmp return_iteration
  257.  
  258.            align 16
  259. pushmatrix:
  260.            push vmatrix+0
  261.            push vmatrix+4
  262.            push vmatrix+8
  263.            push vmatrix+12
  264.            push vmatrix+16
  265.            push vmatrix+20
  266.            push vmatrix+24
  267.            push vmatrix+28
  268.            push vmatrix+32
  269.            jmp return_iteration
  270.  
  271.            align 16
  272. popmatrix:
  273.            pop vmatrix+32
  274.            pop vmatrix+28
  275.            pop vmatrix+24
  276.            pop vmatrix+20
  277.            pop vmatrix+16
  278.            pop vmatrix+12
  279.            pop vmatrix+8
  280.            pop vmatrix+4
  281.            pop vmatrix+0
  282.            jmp return_iteration
  283.  
  284.            align 16
  285. pushlocation:
  286.            push xad
  287.            push yad
  288.            push zad
  289.            jmp return_iteration
  290.  
  291.            align 16
  292. poplocation:
  293.            pop zad
  294.            pop yad
  295.            pop xad
  296.            jmp return_iteration
  297.  
  298.            align 16
  299. ld_special:
  300.            mov cx,ax
  301.            and ecx,special-1      ; max 127 commands
  302.            jmp [special_commands+ecx*4]
  303.  
  304.            align 16
  305.  
  306. ; handle loading of bitmap from object list
  307. ;
  308. ; eg dw himap,8,5,50,60 ;command is 32,point 8, bitmap 5, x&y scaling of 50,60
  309.  
  310. dobitmap:
  311.            align 16
  312.  
  313.            lodsw                  ; get from si, first is point
  314.            shl eax,2
  315.            add eax,lindex         ; add to include offset in list
  316.            stosw                  ; put in sides table
  317.  
  318.            mov edx,ebp            ; save indexer
  319.            movzx ebp,ax           ; get point indexers
  320.            mov eax,zp[ebp]
  321.            mov zeds[ebx*2],eax    ; set zed for sort.
  322.            mov ebp,edx
  323.  
  324.            movsw                  ; get bitmap type
  325.            movsd                  ; get x then y scaling
  326.  
  327.            mov edx,command        ; get command (for iteration bits)
  328.            mov textures[ebx],dx
  329.  
  330.            cmp zad,64000          ; bitmaps farther than 65536 screw up
  331.            jge no_norml           ; you can't see them anyway. prevent overflow
  332.            jmp ln3
  333.  
  334.            align 16
  335.  
  336. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  337. ; Loadsides: Load connection data from object data definition
  338. ; In:
  339. ;  ESI -> offset of connection data
  340. ; Out: null
  341. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  342.  
  343. loadsides:
  344.            mov lamflag,no
  345.            mov edi,offsides       ; get ready for lodsw and stosw
  346.            mov ebp,edi            ; ebp = offset to first point in side
  347.            mov ebx,showing        ; bx = word indexer for surfaces
  348.            shl ebx,1
  349. ld_lp:
  350.            mov ax,[esi]           ; get command word
  351.            add esi,2
  352.            mov command,eax
  353.  
  354.            test eax,special       ; if bitmap, do special load,
  355.            jnz ld_special         ; or test previous color
  356.  
  357.            mov eax,[esi]          ; get texture data/type
  358.            mov texture12,eax
  359.  
  360.            mov eax,[esi+4]        ; get colour, high byte is other side
  361.            add esi,8
  362.            mov colors12,eax
  363.  
  364.            mov ecx,lindex         ; quick add for loop
  365.  
  366.            push ebp
  367.            push ebx
  368.  
  369.            movzx eax,w [esi]      ; get from esi, first is unconditinal
  370.            add esi,2
  371.            shl eax,2
  372.            add eax,ecx            ; add to include offset in list
  373.            mov [edi],ax           ; put in edi
  374.            add edi,2
  375.            mov edx,eax
  376. ld_loop:
  377.            lodsw                  ; get from esi
  378.            shl eax,2
  379.            add eax,ecx
  380.            mov [edi],ax           ; put in edi
  381.            cmp eax,edx            ; check all after first point
  382.            je s ld_exitloop
  383.  
  384.            lodsw
  385.            shl eax,2
  386.            add eax,ecx
  387.            mov [edi+2],ax
  388.            cmp eax,edx
  389.            je s ld_exitloop
  390.  
  391.            lodsw
  392.            shl eax,2
  393.            add eax,ecx
  394.            mov [edi+4],ax
  395.            cmp eax,edx
  396.            je s ld_exitloop
  397.  
  398.            lodsw
  399.            shl eax,2
  400.            add eax,ecx
  401.            mov [edi+6],ax
  402.            add edi,8
  403.            cmp eax,edx
  404.            jne s ld_loop
  405.  
  406. ld_exitloop:
  407.            push esi
  408.  
  409.            mov edi,ebp            ; adjust bp into appropriate indexer
  410.  
  411.            movzx ebp,w [edi+2]
  412.            mov ecx,[zp+ebp]
  413.            mov ebp,edx            ; get point indexers
  414.            add ecx,[zp+ebp]       ; take average of two z points for sort
  415.            mov zeds[ebx*2],ecx
  416.  
  417.            mov edx,command
  418.  
  419.            test edx,onscr         ; find if test is for on screen pixels
  420.            jnz test_if_on_screen
  421.            test dl,both           ; check if always visible
  422.            jnz its_line
  423.  
  424. return_screen:
  425.            mov edx,[xp+ebp]       ; first point
  426.            mov ebx,[yp+ebp]
  427.  
  428.            mov bp,[edi+2]
  429.            mov esi,[xp+ebp]       ; second point
  430.            mov ecx,[yp+ebp]
  431.  
  432.            mov bp,[edi+4]
  433.            mov edi,[xp+ebp]       ; third point
  434.            mov ebp,[yp+ebp]
  435.  
  436.            call checkfront        ; check if side is visable using p1,2,3
  437.  
  438.            pop esi ebx ebp        ; return object data pointer
  439.  
  440.            mov edx,command
  441.            or ecx,ecx
  442.            jle s test_shading     ; cx>-1 if side visible, skip if not
  443.            test edx,double        ; test to use other colour
  444.            jz s skipit            ; miss this side...
  445.            shr texture12,16
  446.            shr colors12,16
  447.            xor w texture12,inverse ; do inverse shading
  448. test_shading:
  449.            test texture12,shade+last
  450.            jnz handle_shading     ; shading bit set, do it...
  451. ln2:
  452.            test edx,check         ; find out if side is only a test side
  453.            jnz s no_show
  454.  
  455.            mov eax,texture12      ; another side added...
  456.            mov textures[ebx],ax
  457.            movzx eax,w colors12
  458.            add eax,palxrefx       ; get offset of palette cross reference table for this object
  459.            mov ax,[eax]
  460.            mov surfcolors[ebx],ax
  461. ln3:
  462.            inc showing            ; another side added...
  463.            add ebx,2
  464.            add ebp,maxpolys*2     ; bump ebp to next block
  465. no_show:
  466.            test edx,iterate
  467.            jnz handle_surface_iteration
  468. skipit:
  469.            test edx,normal        ; do we skip surface normal data
  470.            jz s no_norml
  471.            add esi,6
  472. no_norml:
  473.            test edx,iterate
  474.            jnz failed_iteration   ; skip iteration data if surface failure
  475.  
  476. return_iteration:
  477.            mov edi,ebp            ; set di for next stosw
  478.  
  479.            dec numsides           ; count for next side
  480.            jne ld_lp
  481.  
  482.            mov offsides,edi       ; save for next call
  483.  
  484.            ret
  485.  
  486.            align 16
  487. its_line:
  488.            pop esi ebx ebp
  489.            test w texture12,shade+last
  490.            jz ln2
  491.  
  492. ; handle gourad/lambert shading
  493.  
  494.            align 16
  495. handle_shading:
  496.            test w texture12,last  ; test to use previous colour or bitmap call
  497.            jnz ld_do_previous
  498.  
  499.            test w texture12,wavey
  500.            jnz ln2
  501.  
  502.            push ebx esi ebp edx
  503.  
  504.            cmp lamflag,no         ; is lambert matrix set up?
  505.            je s setitup           ; jump to less likely route
  506. returnq:
  507.            mov bx,word ptr [esi]  ; get surface normal
  508.            mov cx,word ptr [esi+2]
  509.            mov bp,word ptr [esi+4]
  510.            add esi,6
  511.            call lrotate           ; rotate surface normal by lambert matrix
  512.  
  513.            pop edx
  514.            test w texture12,inverse ; have the sides flipped? test dx,256
  515.            jnz s invert_colour    ; jump to least likely route
  516. lp_contin:
  517.            add edi,256
  518.            shr edi,1              ; result -256 to +256, turn into 0-256
  519.            mov al,b shading_tables[edi] ; now into 0-15
  520.            xor ah,ah
  521.  
  522.            pop ebp esi ebx
  523.  
  524.            add w colors12,ax      ; user can have offset color in object!
  525.  
  526.            jmp ln2
  527.  
  528.            align 16
  529. invert_colour:                    ; inversion occures with other side option,
  530.            neg edi                ; always visible option, and shading option
  531.            jmp lp_contin          ; all combined!
  532.  
  533.            align 16
  534. setitup:
  535.            push esi
  536.            mov esi,currobj        ; this is object # from make1obj
  537.            call lambert           ; set up lambert maxtrix
  538.            mov lamflag,yes
  539.            pop esi
  540.            jmp s returnq
  541.  
  542.            align 16
  543.  
  544. ld_do_previous:
  545.            mov ax,w colors12
  546.            mov cx,surfcolors[ebx-2]
  547.            and cx,shading_bits    ; drop old colour block, keep shading indexer (from math.inc)
  548.            add ecx,eax            ; add new colour block
  549.            mov w colors12,cx
  550.  
  551.            jmp ln2
  552.  
  553. ; handle iteration option
  554.  
  555.            align 16
  556.  
  557. handle_surface_iteration:
  558.            test edx,normal
  559.            jz s no_norml2
  560.            add esi,6              ; skip if shading normal present
  561. no_norml2:
  562.            test edx,matrix        ; test to derive new matrix
  563.            jz no_new_matrix
  564. newobject:
  565.            mov edi,currobj        ; new matrix, get offset object number
  566.            add di,[esi+16]
  567.            test onoff[edi],sub_object_on ; test if sub-object has been turned on...
  568.            jz failed_iteration
  569.  
  570.            mov eax,[esi+24]
  571.            mov minzc,eax
  572.            mov eax,[esi+28]
  573.            mov btolr,eax
  574.            push ebx esi ebp edx   ; save stuff before iteration handle
  575.  
  576.            mov bx,w xs[edi*4]     ; get rotation location
  577.            mov cx,w ys[edi*4]
  578.            mov bp,w zs[edi*4]
  579.            add bx,[esi+10]
  580.            add cx,[esi+12]
  581.            add bp,[esi+14]
  582.            movsx ebx,bx
  583.            movsx ecx,cx
  584.            movsx ebp,bp
  585.  
  586.            push edi
  587.            call rotate            ; z<>0, find rotation location
  588.  
  589.            add xad,ebx
  590.            add yad,ecx
  591.            add zad,ebp
  592.  
  593.            pop esi                ; return object number+offset
  594.            test userotate[esi],no_rotation ; test to use new matrix or add to old
  595.            jnz do_compound_thingy
  596.            call temp_matrix       ; add to old
  597.            call matrix_multiply
  598.            mov eax,minzc
  599.            cmp zad,eax            ; check if new object will be behind camera
  600.            jg done_alterq
  601.            jmp failed_iterationq
  602.  
  603. do_compound_thingy:
  604.            call compound          ; compound new matrix
  605.            mov eax,minzc
  606.            cmp zad,eax            ; check if new object will be behind camera
  607.            jg done_alterq
  608.            jmp failed_iterationq
  609.  
  610. no_new_matrix:
  611.            test b [esi+8],centroid ; is there a centroid offset?
  612.            jz done_alter
  613.            mov eax,[esi+28]
  614.            mov btolr,eax
  615.  
  616.            push ebx esi ebp edx   ; save stuff before centroid handle
  617.            movsx ebx,w [esi+10]   ; no new matrix command, find point
  618.            movsx ecx,w [esi+12]   ; offset (addition)
  619.            movsx ebp,w [esi+14]
  620.  
  621.            call rotate            ; if found, add rotated point to xad,yad,zad
  622.  
  623.            add xad,ebx
  624.            add yad,ecx
  625.            add zad,ebp
  626.  
  627. done_alterq:
  628.            sub zad,1
  629.            adc zad,1
  630.  
  631.            mov ebx,xad            ; test if new xad,yad,zad are within screen boundaries
  632.            mov ecx,yad
  633.            mov ebp,zad
  634.  
  635.            cmul eax,ebx,ratiox    ; use fast constant multiply fo 3d conversion
  636.            idiv ebp
  637.  
  638.            movsx edx,xmins
  639.            sub edx,btolr
  640.            cmp eax,edx            ; tolerance is max object size/ratio
  641.            jl failed_iterationq
  642.            movsx edx,xmaxs
  643.            add edx,btolr
  644.            cmp eax,edx
  645.            jge failed_iterationq
  646.  
  647.            mov ebx,eax
  648.  
  649.            cmul eax,ecx,ratioy
  650.            idiv ebp
  651.  
  652.            movsx edx,ymins
  653.            sub edx,btolr
  654.            cmp eax,edx
  655.            jl failed_iterationq
  656.            movsx edx,ymaxs
  657.            add edx,btolr
  658.            cmp eax,edx
  659.            jge failed_iterationq
  660.  
  661.            mov edi,pointindex
  662.            mov xp[edi],ebx
  663.            mov yp[edi],eax
  664.            mov zp[edi],ebp
  665.            add pointindex,4
  666.  
  667.            pop edx ebp esi ebx
  668.  
  669. done_alter:
  670.            movzx eax,w [esi]      ; get number of extra points in iteration
  671.            add esi,2
  672.            mov numpoints,eax      ; set as counter
  673.            mov ecx,eax            ; save number of extra points for later use
  674.  
  675.            shl eax,2
  676.            add eax,pointindex     ; pointindex = word indexer to last point
  677.            cmp eax,maxpoints*4    ; test for overflow in points tables
  678.            jae abort_all2
  679.  
  680.            lodsw                  ; get number of sides in iteration
  681.            add numsides,eax
  682.  
  683.            add eax,showing
  684.            cmp eax,maxsurfaces-1  ; check for overflow in "sides" tables
  685.            jae abort_all2
  686.  
  687.            add esi,25*2
  688.  
  689.            or ecx,ecx             ; no new points to add? (just surfaces)
  690.            je return_iteration    ; only sides added to iteration, done...
  691.  
  692.            push ebx ebp edx       ; save load and store locations
  693.  
  694.            mov edi,currobj        ; add more points to xp,yp,zp list
  695.            mov bl,userotate[edi]  ; because iteration is visible
  696.  
  697.            mov edi,pointindex     ; movzx edi,pointindex
  698.  
  699.            call middle_load_points
  700.            pop edx ebp ebx
  701.  
  702.            jmp return_iteration
  703.  
  704.            align 16
  705.  
  706. abort_all2:
  707.            add esp,strip_bytes    ; abort from iteration and make1obj
  708.            ret                    ; returning now from makeobjs call
  709.  
  710. ; perform test for option 1024 - generate iteration if points on screen.
  711. ; routine also tests if polygon crosses screen - eg no point is on the screen
  712. ; but the polygon covers the screen, like the front of a very big building.
  713.  
  714.            align 16
  715.  
  716. test_if_on_screen:
  717.            xor bl,bl              ; bl = quadrant flag
  718.            push edx edi           ; save command
  719.  
  720.            mov esi,ebp
  721. tios:
  722.            mov ecx,xp[esi]        ; cx, dx =(x,y) to test
  723.            mov edx,yp[esi]
  724.  
  725.            mov ah,32              ;  32 16  8    determine where point is,
  726.            cmp cx,xmins           ;1  x  x  x    then or bl with location
  727.            jl s ytest             ;2  x  x  x
  728.            mov ah,8               ;4  x  x  x
  729.            cmp cx,xmaxs           ;
  730.            jge s ytest
  731.            mov ah,16
  732. ytest:
  733.            mov al,1
  734.            cmp dx,ymins
  735.            jl s oritall
  736.            mov al,4
  737.            cmp dx,ymaxs
  738.            jge s oritall
  739.  
  740.            cmp ah,16
  741.            je s on_screen         ; a point is on the screen, generate side...
  742. oritall:
  743.            or bl,ah               ; point is not on the screen, but it may
  744.            or bl,al               ; contribute to a polygon which covers the screen.
  745.  
  746.            add edi,2              ; get next connection for another test
  747.            mov si,sides[edi]
  748.            cmp si,bp              ; test if at last connection in iteration test
  749.            jne tios
  750.  
  751.            xor al,al              ; count number of bits in y (must be >2)
  752.            ror bl,1
  753.            adc al,0
  754.            ror bl,1
  755.            adc al,0
  756.            ror bl,1
  757.            adc al,0
  758.            cmp al,1
  759.            jbe s skipit2
  760.  
  761.            xor al,al              ; now count x (must be >2)
  762.            ror bl,1
  763.            adc al,0
  764.            ror bl,1
  765.            adc al,0
  766.            ror bl,1
  767.            adc al,0
  768.            cmp al,1
  769.            jbe s skipit2
  770. on_screen:
  771.            pop edi edx
  772.  
  773.            test edx,both          ; side is on screen
  774.            jz return_screen       ; test if alway visible
  775.  
  776.            pop esi ebx ebp        ; always, pop and test for shading
  777.            test edx,shade
  778.            jz ln2                 ; no shading - do normal return
  779.            jmp handle_shading
  780.  
  781. skipit2:
  782.            pop edi edx esi ebx ebp
  783.            jmp skipit
  784.  
  785. ; handle failure of option 512
  786.  
  787.            align 16
  788.  
  789. failed_iterationq:
  790.            pop edx ebp esi ebx
  791.  
  792. failed_iteration:
  793.            movzx ecx,w [esi+4]    ; number of bytes to skip in case of failure
  794.            mov ax,[esi+6]         ; get number of points TOTAL in iteration
  795.            add esi,8
  796.            shl eax,2              ; in case iteration in iteration in iteration...
  797.            add w pointindex,ax
  798.            add esi,ecx
  799.            jmp return_iteration
  800.  
  801.            align 16
  802.  
  803. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  804. ; Make1obj: Handle plotting of object ESI
  805. ; In:
  806. ;   ESI -> object #
  807. ; OUT:null
  808. ; Notes:
  809. ; Routine assumes object is already ON!  note: esi not si!
  810. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  811.  
  812. make1obj:
  813.            mov lamflag,no
  814.            mov currobj,esi
  815.  
  816.            mov ebx,xs[esi*4]      ; displacement
  817.            sub ebx,eyex
  818.            mov ecx,ys[esi*4]
  819.            sub ecx,eyey
  820.            mov ebp,zs[esi*4]
  821.            sub ebp,eyez
  822.  
  823.            test userotate[esi],s_himap+s_point ; check if bitmap or point
  824.            jnz mo_special
  825.  
  826.            shr ebx,8              ; account for decimal places
  827.            test ebx,00800000h
  828.            jz s pm_1
  829.            or ebx, 0ff000000h
  830. pm_1:
  831.            shr ecx,8
  832.            test ecx,00800000h
  833.            jz s pm_2
  834.            or ecx, 0ff000000h
  835. pm_2:
  836.            shr ebp,8
  837.            test ebp,00800000h
  838.            jz s pm_3
  839.            or ebp, 0ff000000h
  840. pm_3:
  841.            mov si,whatshape[esi*2] ; get shape
  842.            mov esi,objbase[esi*4] ; get header start
  843.            add esi,[esi+4]        ; get first resolution
  844.            mov edi,[esi+14*2]     ; get maximum distance seen
  845.  
  846.            cmp ebx,edi            ; check if within visible space
  847.            jnl s noa2             ; if object miles away, don't bother
  848.            cmp ebp,edi
  849.            jnl s noa2
  850.            cmp ecx,edi
  851.            jnl s noa2
  852.            neg edi
  853.            cmp ebp,edi
  854.            jl s noa2
  855.            cmp ebx,edi
  856.            jl s noa2
  857.            cmp ecx,edi
  858.            jg s mo_misout
  859. noa2:
  860.            ret
  861. mo_misout:
  862.            mov edi,dword ptr [esi+16*2]
  863.            mov eax,dword ptr [esi+18*2]
  864.            mov btolr,eax
  865.            call zsolve            ; figure out camera displacement
  866.  
  867.            cmp esi,edi            ; check if behind camera, miminum dist.
  868.            jl s noa2
  869.  
  870.            sub esi,1              ; make z non-zero
  871.            adc esi,1
  872.  
  873.            call xsolve
  874.            mov xad,edi            ; store 3d offsets
  875.            call make3dx           ; now make object farther in 3d
  876.  
  877.            movsx eax,xmins
  878.            sub eax,btolr
  879.            cmp edi,eax            ; tolerance is max object size/ratio
  880.            jl s noa2
  881.            movsx eax,xmaxs
  882.            add eax,btolr
  883.            cmp edi,eax
  884.            jge s noa2
  885.  
  886.            call ysolve            ; solve y and set correct regs
  887.            mov yad,ecx
  888.            call make3dy           ; now make object farther in 3d
  889.  
  890.            movsx eax,ymins
  891.            sub eax,btolr
  892.            cmp ecx,eax
  893.            jl s noa2
  894.            movsx eax,ymaxs
  895.            add eax,btolr
  896.            cmp ecx,eax
  897.            jge noa2
  898.  
  899.            mov zad,ebp
  900.            mov zedthis,ebp
  901.            mov esi,pointindex
  902.  
  903.            mov xp[esi],ebx        ; save center of gravity as point 0
  904.            mov yp[esi],ecx
  905.            mov zp[esi],ebp
  906.  
  907.            mov esi,currobj        ; pop original object number
  908.  
  909.            xor ebx,ebx
  910.            mov bl,palxref[esi]
  911.            mov ebx,xreftable[ebx*4]
  912.            mov palxrefx,ebx
  913.  
  914.            test userotate[esi],no_rotation ; test to call compound routine
  915.            jnz s mk_skipc         ; skip if anything other than full rotations
  916.            call compound          ; full rotation object, calc. matrix
  917. mk_skipc:
  918.            call loadpoints        ; load points and rotate, exit di=sides
  919.            jmp  loadsides         ; now load sides, starting at di
  920.  
  921.            align 16
  922. noa:
  923.            ret
  924.  
  925.            align 16
  926.  
  927. ; if userotate = 32 then draw bitmap at location x,y,z
  928.  
  929. mo_special:
  930.            mov edi,maxz*256
  931.            cmp ebx,edi            ; check if within visible space
  932.            jnl s noa              ; if object miles away, don't bother
  933.            cmp ebp,edi
  934.            jnl s noa
  935.            cmp ecx,edi
  936.            jnl s noa
  937.            neg edi
  938.            cmp ebp,edi
  939.            jl s noa
  940.            cmp ebx,edi
  941.            jl s noa
  942.            cmp ecx,edi
  943.            jl s noa
  944.  
  945.            shr ebx,8              ; account for decimal places, /256
  946.            test ebx,00800000h
  947.            jz s pq_1
  948.            or ebx, 0ff000000h
  949. pq_1:
  950.            shr ecx,8
  951.            test ecx,00800000h
  952.            jz s pq_2
  953.            or ecx, 0ff000000h
  954. pq_2:
  955.            shr ebp,8
  956.            test ebp,00800000h
  957.            jz s pq_3
  958.            or ebp, 0ff000000h
  959. pq_3:
  960.  
  961.            call zsolve            ; figure out camera displacement
  962.  
  963.            cmp esi,minz           ; check if behind camera, miminum dist.
  964.            jl noa2
  965.  
  966.            call xsolve
  967.            mov xad,edi            ; store 3d offsets
  968.            call make3dx           ; now make object farther in 3d
  969.  
  970.            cmp edi,xmit           ; tolerance is max object size/ratio
  971.            jl noa
  972.            cmp edi,xmat
  973.            jge noa
  974.  
  975.            call ysolve            ; solve y and set correct regs
  976.            mov yad,ecx
  977.            call make3dy           ; now make object farther in 3d
  978.  
  979.            cmp ecx,ymit
  980.            jl noa
  981.            cmp ecx,ymat
  982.            jge noa
  983.  
  984.            mov zad,ebp
  985.            mov zedthis,ebp        ; store z for next sort
  986.            mov esi,currobj        ; pop original object number
  987.  
  988.            cmp pointindex,(maxpoints-1)*2 ; check if there is room in table
  989.            jge noa
  990.            cmp showing,maxsurfaces-1
  991.            jge noa
  992.  
  993.            test userotate[esi],s_point ; is point or bitmap?
  994.            jnz mo_ispoint
  995.  
  996.            cmp ebp,65535          ; far bitmaps screw up, abort
  997.            jge noa
  998.  
  999.            mov edi,pointindex
  1000.            mov [xp+edi],ebx       ; set location of bitmap
  1001.            mov [yp+edi],ecx
  1002.            mov [zp+edi],ebp
  1003.  
  1004.            mov edi,offsides
  1005.            add offsides,maxpolys*2 ; update for next object/bitmap
  1006.  
  1007.            mov ebx,showing
  1008.            shl ebp,1              ; adjust so it's the same as loadsides
  1009.            mov zeds[ebx*4],ebp    ; set z sort indexer
  1010.  
  1011.            inc showing            ; one more surface...
  1012.            xor ah,ah
  1013.            mov al,userotate[esi]
  1014.            mov textures[ebx*2],ax ; set command for bitmap
  1015.  
  1016.            mov eax,pointindex
  1017.            add pointindex,4
  1018.            stosw
  1019.            mov ax,whatshape[esi*2]
  1020.            stosw
  1021.            mov ax,vxs[esi*2]      ; set x and y scales (stretching)
  1022.            stosw
  1023.            mov ax,vys[esi*2]
  1024.            stosw
  1025. noa4:
  1026.            ret
  1027.  
  1028.            align 16
  1029.  
  1030. mo_ispoint:
  1031.            cmp bx,xmins            ; draw single point/bullet
  1032.            jl s noa4
  1033.            cmp bx,xmaxs
  1034.            jge s noa4
  1035.            cmp cx,ymins
  1036.            jl s noa4
  1037.            cmp cx,ymaxs            ; ymaxs1 if larger pixel
  1038.            jge s noa4
  1039.  
  1040.            mov edi,pointindex
  1041.            mov [xp+edi],ebx        ; set location of point/bitmap
  1042.            mov [yp+edi],ecx
  1043.            mov [zp+edi],ebp
  1044.  
  1045.            mov edi,offsides
  1046.            add offsides,maxpolys*2 ; update for next object/bitmap
  1047.  
  1048.            mov ebx,showing
  1049.            shl ebx,1
  1050.            shl ebp,1
  1051.            mov zeds[ebx*2],ebp     ; set z sort indexer
  1052.  
  1053.            inc showing             ; one more surface...
  1054.  
  1055.            mov textures[ebx],64    ; set this command as point
  1056.            mov surfcolors[ebx],bulletcolour ; only for variable colours
  1057.  
  1058.            mov eax,pointindex
  1059.            add pointindex,4
  1060.  
  1061.            stosw
  1062.            stosw
  1063. noa8:
  1064.            ret
  1065.  
  1066.            align 16
  1067.  
  1068. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1069. ; Set_order: Initialize original order for plotting objects
  1070. ;  In=Out=null
  1071. ; Notes:  This is called by Flush_surfaces so no need for you to do it.
  1072. ; This must be called every frame to re-initalize the order for polygon sorting
  1073. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1074.  
  1075. set_order:
  1076.            mov ecx,showing
  1077.            jcxz s non2_do
  1078.            dec ecx
  1079.            jz s non2_do
  1080.            shl ecx,1
  1081.            mov esi,ecx
  1082.            shl esi,1
  1083.            add esi,offset order
  1084.  
  1085.            prc equ 8
  1086.  
  1087.            cmp ecx,prc*2
  1088.            jb s ordrloop
  1089. bigsloop:
  1090.            i=0
  1091.            rept prc
  1092.            mov [esi+i],ecx
  1093.            i=i-4
  1094.            sub ecx,2
  1095.            endm
  1096.            jz s non2_do
  1097.            sub esi,prc*4
  1098.            cmp ecx,prc*2
  1099.            jae s bigsloop
  1100. ordrloop:
  1101.            mov [esi],ecx
  1102.            sub esi,4
  1103.            dec ecx
  1104.            loop ordrloop
  1105. non2_do:
  1106.            mov [order],0           ; fill last
  1107.  
  1108.            ret
  1109.  
  1110.            align 16
  1111.  
  1112. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1113. ; Setmakeorder: Initialize original order for plotting objects
  1114. ;  In=Out=null
  1115. ; Notes:  This is called by init_tables so there is no need for you to do it.
  1116. ; This  must  be  called  once  at  the  beginging of the program  to  define
  1117. ; in what order the objects must be plotted (back to front).   The  order  is
  1118. ; constantly being re-arranged as objects move in front an behind one another
  1119. ; If you want to do windowing, save the makeorder table for each window.
  1120. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1121.  
  1122. set_makeorder:
  1123.  
  1124.            i=0
  1125.            rept maxobjects        ; macro to produce unrolled loop
  1126.            mov makeorder+i*2,i+1  ; set makeorder to 0,1,2,3,4
  1127.            i=i+1
  1128.            endm
  1129.  
  1130.            ret
  1131.  
  1132.            align 16
  1133.  
  1134. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1135. ; Makeobjs: Make/plot all objects on current_page
  1136. ;  In=Out=null
  1137. ; Notes: Called from your mainline animation routine, falls through to sort
  1138. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1139.  
  1140. makeobjs:                         ; make all objects, unrolled loop
  1141.            mov offsides, offset sides ; clear table indexers for call
  1142.            mov pointindex,0
  1143.            mov zedthis,0          ; clear temp (last z location)
  1144.  
  1145.            i=0
  1146.  
  1147.            rept maxobjects
  1148.            local itsoff, dont_flush
  1149.  
  1150.            mov eax,32767          ; in case of abort
  1151.            movzx esi,makeorder+i*2
  1152.            test onoff[esi],mainobject_on ; check on/off
  1153.            jz s itsoff
  1154.  
  1155.            if i ne 0
  1156.  
  1157.            movsx eax,finalzed+i*2 ; flush buffer if this object far away
  1158.            sub eax,zedthis        ; from last.  dont flush if very close.
  1159.            add eax,collision/2
  1160.            cmp eax,collision
  1161.            jae s dont_flush
  1162.  
  1163.            call flush_surfaces    ; flush previous object
  1164.  
  1165. dont_flush:
  1166.            movzx esi,makeorder+i*2
  1167.            endif
  1168.  
  1169.            call make1obj          ; put new object in buffer
  1170.  
  1171.            mov eax,zedthis        ; get z and save for re_sort, zedthis = temporary storage
  1172. itsoff:
  1173.            mov finalzed+i*2,ax
  1174.  
  1175.            i=i+1
  1176.            endm
  1177.  
  1178.            cmp showing,0          ; if objects have already been flushed, skip
  1179.            je miss_flush
  1180.            call flush_surfaces
  1181. miss_flush:
  1182.  
  1183. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1184. ; Re_sort:Bubble sort for entire objects, fastest when already sorted (assumed)
  1185. ;  In=Out=null
  1186. ; Notes: No need to ever call this routine as makeobjs falls through to here.
  1187. ; This routine sorts the objects make order by the prevoius Z distance.
  1188. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1189.  
  1190.            basedif equ offset makeorder - offset finalzed
  1191.  
  1192. re_sort:
  1193.            mov ecx,maxobjects-1
  1194.            mov edx,offset finalzed-2
  1195.            xor ebx,ebx            ; sort flag
  1196.            xor esi,esi
  1197. nextccx:
  1198.            add edx,2
  1199.            mov esi,maxobjects*2-2+offset finalzed
  1200. nextddx:
  1201.            sub esi,2
  1202.  
  1203.            mov ax,[esi+2]
  1204.            cmp ax,[esi]
  1205.            jle s donotng
  1206.            xchg ax,[esi]          ; don't flip entire object, just indexers
  1207.            xchg ax,[esi+2]
  1208.            mov ax,basedif[esi+2]
  1209.            xchg ax,basedif[esi]
  1210.            xchg ax,basedif[esi+2]
  1211.            inc ebx                ; flag that one sorted
  1212. donotng:
  1213.            cmp esi,edx
  1214.            jnle s nextddx
  1215.  
  1216.            or ebx,ebx             ; re-sort until no more sorts
  1217.            loopne s nextccx
  1218. quickex:
  1219.            ret
  1220.  
  1221. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1222. ; Flush_surfaces: Sort and flush all surfaces from polygon buffer to screen
  1223. ;  In=Out=null
  1224. ; Notes: called by makeobjs
  1225. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1226.  
  1227. flush_surfaces:
  1228.            call set_order     ; set ordering of sides
  1229.            call sort_list     ; sort sides according to z distance
  1230.            call drawvect      ; draw 'em on da screen
  1231.  
  1232.            mov offsides, offset sides ; clear table indexers for call
  1233.            mov pointindex,0
  1234.  
  1235.            ret
  1236.  
  1237. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1238. ; Init_tables: Initialize ordering before beginning 3d animation
  1239. ;  In=Out=null
  1240. ; Notes: Called by YOU. Different routines between 3d1,3d2 and 3d3
  1241. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1242.  
  1243. init_tables:
  1244.            call set_makeorder
  1245.            ret
  1246.  
  1247. code32     ends
  1248.            end
  1249.